package com.golden.procedure.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.golden.procedure.dao.SiteSchedulingTemplateDetailMapper;
import com.golden.procedure.dao.WorkOrderPhotographyMapper;
import com.golden.procedure.dao.WorkSeatSchedulingMapper;
import com.golden.procedure.dao.WorkSiteSchedulingMapper;
import com.golden.procedure.dao.WorkSiteSeatMapper;
import com.golden.procedure.domain.WorkSchedulingSettingDO;
import com.golden.procedure.domain.WorkSiteSchedulingDO;
import com.golden.procedure.domain.WorkSiteSeatDO;
import com.golden.procedure.entity.SiteSchedulingTemplateDetail;
import com.golden.procedure.entity.SiteSchedulingTemplateDetailExample;
import com.golden.procedure.entity.WorkSeatScheduling;
import com.golden.procedure.entity.WorkSeatSchedulingExample;
import com.golden.procedure.entity.WorkSiteScheduling;
import com.golden.procedure.entity.WorkSiteSchedulingExample;
import com.golden.procedure.entity.WorkSiteSeat;
import com.golden.procedure.entity.WorkSiteSeatExample;
import com.golden.procedure.query.SchedulingQueryDO;
import com.golden.procedure.result.ResultDO;
import com.golden.procedure.result.ResultSupport;
import com.golden.procedure.service.IWorkSeatSchedulingService;
import com.golden.procedure.service.IWorkSiteSchedulingService;
import com.golden.procedure.service.IWorkSiteSeatService;
import com.golden.procedure.util.BeanUtilsExtends;
import com.golden.procedure.util.BonConstant;

@Service("workSiteSchedulingService")
public class WorkSiteSchedulingService extends BaseService implements IWorkSiteSchedulingService {

	@Autowired
	WorkSiteSeatMapper workSiteSeatMapper;
	@Autowired
	WorkSiteSchedulingMapper workSiteSchedulingMapper;
	@Autowired
	WorkSeatSchedulingMapper workSeatSchedulingMapper;
	@Autowired
	SiteSchedulingTemplateDetailMapper templateDetailMapper;
	@Autowired
	WorkOrderPhotographyMapper workOrderPhotographyMapper;
	@Autowired
	IWorkSiteSeatService workSiteSeatService;
	@Autowired
	IWorkSeatSchedulingService workSeatSchedulingService;

	/**
	 * 创建摄控设置 <b>Description:新增日程表、工位分组表、席位表数据， 新创建或从模板导入，状态为：未开放状态</b><br>
	 * 
	 * @param domain
	 * @return ResultDO
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月17日 下午4:37:11 <br>
	 *       <b>Version:</b> 1.0
	 */
	@Override
	public ResultDO add(WorkSchedulingSettingDO domain) {
		ResultDO result = new ResultSupport();
		// 1.数据验证
		if (isNumberInValid(domain.getSiteID())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("上门组ID为空");
			result.setSuccess(false);
			return result;
		}
		// 2.获取日期
		SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm");
		Date dateStart = new Date(Long.parseLong(domain.getSchedulingDateStart()));
		Date dateEnd = new Date(Long.parseLong(domain.getSchedulingDateEnd()));
		if (dateStart.compareTo(dateEnd) > 0) {
			// 日期格式不正确
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("摄控日期格式错误");
			result.setSuccess(false);
			return result;
		}

		// 删除重叠时间段内原有数据
		deleteSetting(domain);

		// 3.批量导入日程数据
		List<WorkSiteScheduling> list = new ArrayList<WorkSiteScheduling>();
		Date schedulingDate = dateStart;
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(schedulingDate);
		while (schedulingDate.compareTo(dateEnd) <= 0) {
			WorkSiteScheduling siteScheduling = new WorkSiteScheduling();
			// 上门组id
			siteScheduling.setSiteID(domain.getSiteID());
			siteScheduling.setSchedulingDate(schedulingDate);
			// 未开放状态
			siteScheduling.setIsDelete(BonConstant.DB_NOT_ACTIVITY);
			// 是否是休息日（默认不是）
			siteScheduling.setIsDayoff(BonConstant.DAYOFF_NO);
			if (null != domain.getDayoff()) {
				// 是否是休息日
				if (domain.getDayoff().contains(getWeekday(calendar))) {
					siteScheduling.setIsDayoff(BonConstant.DAYOFF_YES);
				}
			}
			siteScheduling.setAuthorID(domain.getAuthorID());
			siteScheduling.setAuthor(domain.getAuthor());
			siteScheduling.setCreatetime(Calendar.getInstance().getTime());
			list.add(siteScheduling);

			calendar.add(Calendar.DAY_OF_MONTH, 1);
			schedulingDate = calendar.getTime();
		}

		// mybatis批量插入日程数据
		if (list.size() > 0) {
			workSiteSchedulingMapper.insertBatch(list);
		}

		// 4. 批量导入工位分组数据
		// 4.1 查询日程
		WorkSiteSchedulingExample example = new WorkSiteSchedulingExample();
		WorkSiteSchedulingExample.Criteria criteria = example.createCriteria();
		criteria.andSiteIDEqualTo(domain.getSiteID()); // 上门组
		criteria.andSchedulingDateBetween(dateStart, dateEnd); // 日期区间
		criteria.andIsDayoffEqualTo(BonConstant.DAYOFF_NO); // 非休息日
		criteria.andIsDeleteEqualTo(BonConstant.DB_NOT_ACTIVITY); // 未开放

		list = workSiteSchedulingMapper.selectByExample(example);
		if (null == list || list.size() == 0) {
			// 摄控日期为休息日，无分组和席位
			return result;
		}

		// 4.2判断是否使用模板: 按工位分组存放席位数据
		Map<Integer, List<SiteSchedulingTemplateDetail>> seatMap = new HashMap<Integer, List<SiteSchedulingTemplateDetail>>();
		if (BonConstant.SCHEDULING_TEMPLATE_USED == domain.getIsUseTemplate()) {
			// 4.1 读取模板数据
			SiteSchedulingTemplateDetailExample templateExample = new SiteSchedulingTemplateDetailExample();
			SiteSchedulingTemplateDetailExample.Criteria templateCriteria = templateExample.createCriteria();
			templateCriteria.andTemplateIDEqualTo(domain.getTemplateID());
			templateExample.setOrderByClause(" seatGroupIndex asc, planStartOn asc ");
			List<SiteSchedulingTemplateDetail> templist = templateDetailMapper.selectByExample(templateExample);
			if (null == templist || templist.size() == 0) {
				// 未找到模板数据
				result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("模板数据查询失败");
				result.setSuccess(false);
				return result;
			}
			// 工位分组处理
			List<SiteSchedulingTemplateDetail> dataList = new ArrayList<SiteSchedulingTemplateDetail>();
			int groupIndex = templist.get(0).getSeatGroupIndex();
			int index = 1; // 工位分组序号（从1开始）
			dataList.add(templist.get(0));
			for (int i = 1; i < templist.size(); i++) {
				if (groupIndex == templist.get(i).getSeatGroupIndex()) {
					dataList.add(templist.get(i));
					continue;
				}
				seatMap.put(index++, dataList);
				groupIndex = templist.get(i).getSeatGroupIndex();
				dataList = new ArrayList<SiteSchedulingTemplateDetail>();
				dataList.add(templist.get(i));
			}
			if (dataList.size() > 0) {
				seatMap.put(index, dataList);
			}
			// 工位分组数
			domain.setMaxSeatGroup(index);
		}

		// 4.3 批量导入工位分组数据
		List<WorkSiteSeat> siteSeatList = new ArrayList<WorkSiteSeat>();
		for (int i = 0; i < list.size(); i++) {
			// 生成工位分组数据
			for (int j = 1; j <= domain.getMaxSeatGroup(); j++) {
				siteSeatList.add(getSiteSeat(domain.getSiteID(), list.get(i).getId(), list.get(i).getSchedulingDate(),
						j, domain.getAuthorID(), domain.getAuthor()));
			}
		}
		// 4.4 mybatis批量插入工位数据
		if (siteSeatList.size() > 0) {
			workSiteSeatMapper.insertBatch(siteSeatList);
		} else {
			// 无分组数据，成功返回
			return result;
		}

		// 5.批量导入席位数据
		// 5.1查询工位分组
		WorkSiteSeatExample siteSeatExample = new WorkSiteSeatExample();
		WorkSiteSeatExample.Criteria siteSeatCriteria = siteSeatExample.createCriteria();
		siteSeatCriteria.andSiteIDEqualTo(domain.getSiteID());
		siteSeatCriteria.andSchedulingDateBetween(dateStart, dateEnd);
		siteSeatCriteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		siteSeatExample.setOrderByClause(" schedulingDate asc, seatGroupIndex asc ");

		siteSeatList = workSiteSeatMapper.selectByExample(siteSeatExample);
		// 5.2 获取时段数据
		String[] timeFrame = new String[] {};
		if (domain.getIsUseTemplate() == BonConstant.SCHEDULING_TEMPLATE_NOUSE) {
			timeFrame = domain.getPlanStartOnStr().split(",");
		}
		// 5.2 批量导入席位数据
		List<WorkSeatScheduling> seatSchedulingList = new ArrayList<WorkSeatScheduling>();
		for (int i = 0; i < siteSeatList.size(); i++) {
			// 生成工位分组数据
			int seatGroupIndex = siteSeatList.get(i).getSeatGroupIndex();
			if (domain.getIsUseTemplate() == BonConstant.SCHEDULING_TEMPLATE_USED
					&& seatMap.containsKey(seatGroupIndex)) {
				// 5.3.根据模板，循环插入席位数据
				for (int j = 0; j < seatMap.get(seatGroupIndex).size(); j++) {
					SiteSchedulingTemplateDetail daTemplateDetail = seatMap.get(seatGroupIndex).get(j);
					seatSchedulingList.add(getSeatScheduling(siteSeatList.get(i), daTemplateDetail.getPlanStartOn(),
							seatGroupIndex, domain.getAuthorID(), domain.getAuthor()));
				}
			} else {
				// 5.4.根据拍摄时段，循环插入席位数据
				for (int j = 0; j < timeFrame.length; j++) {
					try {
						seatSchedulingList.add(getSeatScheduling(siteSeatList.get(i), sdfTime.parse(timeFrame[j]),
								seatGroupIndex, domain.getAuthorID(), domain.getAuthor()));
					} catch (ParseException e) {
						e.printStackTrace();
					}
				}
			}
		}
		// mybatis批量插入席位数据
		if (seatSchedulingList.size() > 0) {
			workSeatSchedulingMapper.insertBatch(seatSchedulingList);
		}

		return result;
	}

	/**
	 * 保存摄控设置 <b>Description:修改日程表数据状态为开放状态</b><br>
	 * 
	 * @param domain
	 * @return ResultDO
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月17日 下午4:36:54 <br>
	 *       <b>Version:</b> 1.0
	 */
	@Override
	public ResultDO saveSetting(WorkSchedulingSettingDO domain) {

		ResultDO result = new ResultSupport();

		if (isNumberInValid(domain.getSiteID())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("上门组ID为空");
			result.setSuccess(false);
			return result;
		}
		if (StringUtils.isEmpty(domain.getSchedulingDateStart())
				|| StringUtils.isEmpty(domain.getSchedulingDateEnd())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("日期为空");
			result.setSuccess(false);
			return result;
		}

		WorkSiteSchedulingExample siteExample = new WorkSiteSchedulingExample();
		WorkSiteSchedulingExample.Criteria siteCriteria = siteExample.createCriteria();
		siteCriteria.andSiteIDEqualTo(domain.getSiteID());
		siteCriteria.andSchedulingDateBetween(new Date(Long.parseLong(domain.getSchedulingDateStart())),
				new Date(Long.parseLong(domain.getSchedulingDateEnd())));

		// 更新状态：可用
		WorkSiteScheduling entity = new WorkSiteScheduling();
		entity.setIsDelete(BonConstant.DB_NORMAL); // 生效

		workSiteSchedulingMapper.updateByExampleSelective(entity, siteExample);

		return result;
	}

	/**
	 * 清除某天/某段时间的摄控设置，删除所有工位组、席位数据 <b>Description:判断该时间段内是否已有工单：
	 * 无则删除日程、工位及席位数据；有则不允许删除</b><br>
	 * 
	 * @param ids
	 * @return ResultDO
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月17日 下午2:55:03 <br>
	 *       <b>Version:</b> 1.0
	 */
	@Override
	public ResultDO deleteSetting(WorkSchedulingSettingDO domain) {
		ResultDO result = new ResultSupport();
		// 1.基础数据验证
		if (isNumberInValid(domain.getSiteID())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("上门组ID为空");
			result.setSuccess(false);
			return result;
		}
		if (StringUtils.isEmpty(domain.getSchedulingDateStart())
				|| StringUtils.isEmpty(domain.getSchedulingDateEnd())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("日期为空");
			result.setSuccess(false);
			return result;
		}

		// 2.查询时间段内是否有摄控安排（席位是否已被占用）
		if (!workSeatSchedulingService.checkSeatEnable(domain)) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("该上门组在此时间内已分配工单，不可删除");
			result.setSuccess(false);
			return result;
		}

		Date startDate = new Date(Long.parseLong(domain.getSchedulingDateStart()));
		Date endDate = new Date(Long.parseLong(domain.getSchedulingDateEnd()));
		// 3.删除席位
		WorkSeatSchedulingExample seatExample = new WorkSeatSchedulingExample();
		WorkSeatSchedulingExample.Criteria seatCriteria = seatExample.createCriteria();
		seatCriteria.andSiteIDEqualTo(domain.getSiteID());
		seatCriteria.andSchedulingDateBetween(startDate, endDate);

		WorkSeatScheduling entity = new WorkSeatScheduling();
		entity.setIsDelete(BonConstant.DB_DELETE);
		entity.setModifiID(domain.getModifiID());
		entity.setModifi(domain.getModifi());
		entity.setModifitime(Calendar.getInstance().getTime());
		workSeatSchedulingMapper.updateByExampleSelective(entity, seatExample);

		// 3.删除工位分组
		WorkSiteSeatExample siteSeatExample = new WorkSiteSeatExample();
		WorkSiteSeatExample.Criteria siteSeatCriteria = siteSeatExample.createCriteria();
		siteSeatCriteria.andSiteIDEqualTo(domain.getSiteID());
		siteSeatCriteria.andSchedulingDateBetween(startDate, endDate);

		WorkSiteSeat entity1 = new WorkSiteSeat();
		entity1.setIsDelete(BonConstant.DB_DELETE);
		entity1.setModifitime(Calendar.getInstance().getTime());
		entity1.setModifiID(domain.getModifiID());
		entity1.setModifi(domain.getModifi());
		workSiteSeatMapper.updateByExampleSelective(entity1, siteSeatExample);

		// 3.删除日程
		WorkSiteSchedulingExample siteExample = new WorkSiteSchedulingExample();
		WorkSiteSchedulingExample.Criteria siteCriteria = siteExample.createCriteria();
		siteCriteria.andSiteIDEqualTo(domain.getSiteID());
		siteCriteria.andSchedulingDateBetween(startDate, endDate);

		WorkSiteScheduling entity2 = new WorkSiteScheduling();
		entity2.setIsDelete(BonConstant.DB_DELETE);
		entity2.setModifitime(Calendar.getInstance().getTime());
		entity2.setModifiID(domain.getModifiID());
		entity2.setModifi(domain.getModifi());
		workSiteSchedulingMapper.updateByExampleSelective(entity2, siteExample);

		return result;
	}

	/**
	 * 查询某一天或某个时间段内的摄控设置 <b>Description:时间段内查询某一天的摄控设置</b><br>
	 * 
	 * @param query
	 * @return ResultDO
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月17日 下午4:57:00 <br>
	 *       <b>Version:</b> 1.0裴翡
	 */
	@Override
	public ResultDO query(SchedulingQueryDO query) {
		ResultDO result = new ResultSupport();
		// 1.数据验证
		if (isNumberInValid(query.getSiteID())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("上门组ID为空");
			result.setSuccess(false);
			return result;
		}
		if (StringUtils.isEmpty(query.getSchedulingDateStart()) || StringUtils.isEmpty(query.getSchedulingDateEnd())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("摄控时间参数为空");
			result.setSuccess(false);
			return result;
		}
		// 2.查询日程表,查找非工作日日期
		List<WorkSiteSeatDO> siteSeatDOList = new ArrayList<WorkSiteSeatDO>();

		WorkSiteSchedulingExample example = new WorkSiteSchedulingExample();
		WorkSiteSchedulingExample.Criteria criteria = example.createCriteria();
		criteria.andSiteIDEqualTo(query.getSiteID());
		criteria.andSchedulingDateBetween(new Date(Long.parseLong(query.getSchedulingDateStart())),
				new Date(Long.parseLong(query.getSchedulingDateEnd())));
		criteria.andIsDeleteNotEqualTo(BonConstant.DB_DELETE);
		criteria.andIsDayoffEqualTo(BonConstant.DAYOFF_NO);

		List<WorkSiteScheduling> list = workSiteSchedulingMapper.selectByExample(example);
		if (null == list || list.isEmpty()) {
			result.setModel(ResultDO.FIRST_MODEL_KEY, siteSeatDOList);
			return result;
		}
		// 任取一条数据（第一条）
		WorkSiteScheduling siteScheduling = list.get(0);

		// 3.根据工作日查询工位分组表
		WorkSiteSeatExample siteSeatExample = new WorkSiteSeatExample();
		WorkSiteSeatExample.Criteria siteSeatCriteria = siteSeatExample.createCriteria();
		siteSeatCriteria.andSiteSchedulingIDEqualTo(siteScheduling.getId());
		siteSeatCriteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		siteSeatExample.setOrderByClause(" seatGroupIndex asc "); // 按工位分组序号排序

		if (query.isPage()) {
			siteSeatExample.setLimitByPage(query.getStart() + "," + query.getPageRows());
			int count = workSiteSeatMapper.countByExample(siteSeatExample);
			result.setModel(ResultSupport.SECOND_MODEL_KEY, count);
		}

		List<WorkSiteSeat> siteSeatList = workSiteSeatMapper.selectByExample(siteSeatExample);
		if (null != list && !list.isEmpty()) {
			for (WorkSiteSeat seat : siteSeatList) {
				WorkSiteSeatDO siteSeatDO = getWorkSiteSeatDO(seat);
				// 4.根据工位分组，查询工位下的席位
				WorkSeatSchedulingExample seatExample = new WorkSeatSchedulingExample();
				WorkSeatSchedulingExample.Criteria seatCriteria = seatExample.createCriteria();
				seatCriteria.andSiteSeatIDEqualTo(seat.getId());
				seatCriteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
				seatExample.setOrderByClause(" planStartOn asc ");

				List<WorkSeatScheduling> seatSchedulingList = workSeatSchedulingMapper.selectByExample(seatExample);
				siteSeatDO.setSeatList(getWorkSeatSchedulingDOList(seatSchedulingList));
				siteSeatDOList.add(siteSeatDO);
			}
		}
		result.setModel(ResultDO.FIRST_MODEL_KEY, siteSeatDOList);
		return result;
	}

	/**
	 * 查询某个景点的最新摄控日期 <b>Description:</b><br>
	 * 
	 * @param siteID
	 * @return Date
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月17日 下午4:57:26 <br>
	 *       <b>Version:</b> 1.0
	 */
	@Override
	public Date getLatestSchedulingDate(Integer siteID) {
		WorkSiteSchedulingExample example = new WorkSiteSchedulingExample();
		WorkSiteSchedulingExample.Criteria criteria = example.createCriteria();
		criteria.andSiteIDEqualTo(siteID);
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		example.setOrderByClause(" schedulingDate desc ");

		List<WorkSiteScheduling> list = workSiteSchedulingMapper.selectByExample(example);
		if (null != list && list.size() > 0) {
			WorkSiteScheduling siteScheduling = list.get(0);
			return siteScheduling.getSchedulingDate();
		}
		return null;
	}

	/**
	 * 查询摄控日历 <b>Description:</b><br>
	 * 
	 * @param siteID
	 * @return Date
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月17日 下午5:50:51 <br>
	 *       <b>Version:</b> 1.0
	 */
	@Override
	public ResultDO schedulingCalendar(SchedulingQueryDO query) {
		// 摄控日历
		ResultDO result = new ResultSupport();
		// 1.数据验证
		if (isNumberInValid(query.getSiteID()) || StringUtils.isEmpty(query.getCalDate())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}

		// 获取本月日期区间
		Calendar calendar = Calendar.getInstance();
		String calDate = query.getCalDate() + "01";
		try {
			Date date = new SimpleDateFormat("yyyyMMdd").parse(calDate);
			calendar.setTime(date);
		} catch (ParseException e) {
			e.printStackTrace();
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("日期年月格式错误");
			result.setSuccess(false);
			return result;
		}
		Date startDay = calendar.getTime();
		calendar.add(Calendar.MONTH, 1);
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		Date endDay = calendar.getTime();

		// 2. 查询当月内的摄控设置数据
		WorkSiteSchedulingExample example = new WorkSiteSchedulingExample();
		WorkSiteSchedulingExample.Criteria criteria = example.createCriteria();
		criteria.andSiteIDEqualTo(query.getSiteID());
		criteria.andSchedulingDateBetween(startDay, endDay);
		criteria.andIsDeleteNotEqualTo(BonConstant.DB_DELETE);
		example.setOrderByClause(" schedulingDate asc ");

		List<WorkSiteScheduling> list = workSiteSchedulingMapper.selectByExample(example);

		List<WorkSiteSchedulingDO> resList = new ArrayList<WorkSiteSchedulingDO>();
		Map<String, WorkSiteSchedulingDO> map = new HashMap<String, WorkSiteSchedulingDO>();

		if (null != list && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				WorkSiteScheduling data = list.get(i);
				WorkSiteSchedulingDO siteSchedulingDO = new WorkSiteSchedulingDO();
				if (!BeanUtilsExtends.copyProperties(siteSchedulingDO, data)) {
					result.setErrorCode(ResultDO.PARAM_ERROR);
					result.setErrorMsg("数据格式转换错误");
					result.setSuccess(false);
					return result;
				}
				siteSchedulingDO.setSchedulingDateStr(data.getSchedulingDate().getTime() + "");
				// 统计工作日数据
				if (data.getIsDayoff() == BonConstant.DAYOFF_NO) {
					// 统计工位组数
					siteSchedulingDO.setSeatGroupNum(countSeatGroup(siteSchedulingDO));
					// 统计席位数
					siteSchedulingDO.setSeatNum(countSeatNum(siteSchedulingDO, BonConstant.SEAT_STATUS_USED));
					siteSchedulingDO.setSeatTotal(countSeatNum(siteSchedulingDO, null));
					// 统计已拍摄数量（拍摄完成、重拍、补拍）
					siteSchedulingDO.setServiceNum(countServiceNum(query.getSiteID(), data.getSchedulingDate(), null));
				} else {
					siteSchedulingDO.setDayoff("休息");
				}
				map.put(siteSchedulingDO.getSchedulingDateStr(), siteSchedulingDO);
			}
		}

		// 填充日历
		Date schedulingDate = startDay;
		calendar = Calendar.getInstance();
		calendar.setTime(schedulingDate);
		while (schedulingDate.compareTo(endDay) <= 0) {
			// 有摄控数据，填充摄控数据； 无摄控数据，返回当天日期
			if (map.containsKey(schedulingDate.getTime() + "")) {
				resList.add(map.get(schedulingDate.getTime() + ""));
			} else {
				WorkSiteSchedulingDO siteSchedulingDO = new WorkSiteSchedulingDO();
				siteSchedulingDO.setSchedulingDate(schedulingDate);
				siteSchedulingDO.setSchedulingDateStr(schedulingDate + "");
				resList.add(siteSchedulingDO);
			}
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			schedulingDate = calendar.getTime();
		}

		result.setModel(ResultDO.FIRST_MODEL_KEY, resList);
		return result;
	}

	/**
	 * 统计工位组数 <b>Description:统计某一天的工位组数</b><br>
	 * 
	 * @param data
	 * @return Integer
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月18日 上午11:19:40 <br>
	 *       <b>Version:</b> 1.0
	 */
	public Integer countSeatGroup(WorkSiteSchedulingDO siteSchedulingDO) {
		WorkSiteSeatExample example = new WorkSiteSeatExample();
		WorkSiteSeatExample.Criteria criteria = example.createCriteria();
		criteria.andSiteSchedulingIDEqualTo(siteSchedulingDO.getId());
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		int count = workSiteSeatMapper.countByExample(example);
		return count;
	}

	/**
	 * 统计席位 <b>Description:统计某一天的席位数</b><br>
	 * 
	 * @param data
	 * @param status
	 *            席位状态： NULL - 总席位数（空闲+占用，不包含禁用席位） BonConstant.SEAT_STATUS_USED
	 *            - 已使用席位数
	 * @return Integer
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月18日 上午11:19:40 <br>
	 *       <b>Version:</b> 1.0
	 */
	@Override
	public Integer countSeatNum(WorkSiteSchedulingDO siteSchedulingDO, Integer status) {
		WorkSeatSchedulingExample example = new WorkSeatSchedulingExample();
		WorkSeatSchedulingExample.Criteria criteria = example.createCriteria();
		criteria.andSiteSchedulingIDEqualTo(siteSchedulingDO.getId());
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		if (null != status) {
			criteria.andStatusEqualTo(status);
		} else {
			// 总席位数（不包含 禁用席位）
			criteria.andStatusNotEqualTo(BonConstant.SEAT_STATUS_DISABLE);
		}
		int count = workSeatSchedulingMapper.countByExample(example);
		return count;
	}

	/**
	 * 统计已拍摄数量 <b>Description:统计某个用户某一天的已拍摄数量</b><br>
	 * 
	 * @param date
	 *            摄控日期
	 * @param employeeID
	 *            用户ID
	 * @return Integer
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月18日 下午5:51:15 <br>
	 *       <b>Version:</b> 1.0
	 */
	@Override
	public Integer countServiceNum(Integer siteID, Date date, Integer employeeID) {
		// 根据用户、日期查询拍摄数
		Map<String, Object> params = new HashMap<String, Object>();
		// 上门组
		if (!isNumberInValid(siteID)) {
			params.put("siteID", siteID);
		}
		// 日期
		if (null != date) {
			params.put("schedulingDate", date);
		}
		// 用户
		if (!isNumberInValid(employeeID)) {
			params.put("employeeID", employeeID);
		}
		params.put("status", Arrays.asList(new Integer[] { BonConstant.SHOT_STATUS_OK,
				BonConstant.SHOT_STATUS_REPHOTOGRAPH, BonConstant.SHOT_STATUS_RESHOT }));

		return workOrderPhotographyMapper.countServiceNum(params);
	}

	/**
	 * 设置/取消休息日 <b>Description:设置休息日：若当天已有工单预约，则不允许修改； 若无，则将删除当天的工位分组及席位；
	 * 取消休息日，不恢复设置，需要重新创建摄控设置</b><br>
	 * 
	 * @param siteID
	 * @return Date
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月17日 下午5:50:51 <br>
	 *       <b>Version:</b> 1.0
	 */
	@Override
	public ResultDO setDayoff(WorkSiteSchedulingDO domain) {
		// 1.参数验证
		ResultDO result = new ResultSupport();
		// 2.设置休息日时，查询当天是否已安排工单

		Date schedulingDate = new Date(Long.parseLong(domain.getSchedulingDateStr()));
		// 1-设置为休息日
		if (domain.getIsDayoff() == 1) {
			// 查询是否已有日程
			WorkSiteSchedulingExample siteExample = new WorkSiteSchedulingExample();
			WorkSiteSchedulingExample.Criteria siteCriteria = siteExample.createCriteria();
			siteCriteria.andSiteIDEqualTo(domain.getSiteID());
			siteCriteria.andSchedulingDateEqualTo(schedulingDate);
			siteCriteria.andIsDeleteNotEqualTo(BonConstant.DB_DELETE);
			int siteCount = workSiteSchedulingMapper.countByExample(siteExample);
			if (siteCount < 1) {
				// 无设置，则新增日程
				WorkSiteScheduling entity = new WorkSiteScheduling();
				entity.setSiteID(domain.getSiteID());
				entity.setSchedulingDate(schedulingDate);
				entity.setIsDayoff(BonConstant.DAYOFF_YES);
				entity.setIsDelete(BonConstant.DB_NORMAL);
				entity.setAuthorID(domain.getAuthorID());
				entity.setAuthor(domain.getAuthor());
				entity.setCreatetime(Calendar.getInstance().getTime());
				workSiteSchedulingMapper.insert(entity);
				return result;
			}

			// 查询是否已有预约工单
			WorkSeatSchedulingExample seatExample = new WorkSeatSchedulingExample();
			WorkSeatSchedulingExample.Criteria seatCriteria = seatExample.createCriteria();
			seatCriteria.andSiteIDEqualTo(domain.getSiteID());
			seatCriteria.andSchedulingDateEqualTo(schedulingDate);
			seatCriteria.andStatusEqualTo(BonConstant.SEAT_STATUS_USED); // 1 占用
			seatCriteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
			int seatCount = workSeatSchedulingMapper.countByExample(seatExample);
			if (seatCount > 0) {
				result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("本日内已分配工单，不可修改，请先处理已预约工单");
				result.setSuccess(false);
				return result;
			}

			// 如果有工位分组和席位数据，则同步删除,并修改日程
			// 删除工位分组及席位
			SchedulingQueryDO queryDO = new SchedulingQueryDO();
			queryDO.setSiteID(domain.getSiteID());
			queryDO.setSchedulingDateStr(schedulingDate.getTime() + "");
			workSiteSeatService.delBySiteScheduling(queryDO);

			// 更新日程
			siteExample = new WorkSiteSchedulingExample();
			siteCriteria = siteExample.createCriteria();
			siteCriteria.andSiteIDEqualTo(domain.getSiteID());
			siteCriteria.andSchedulingDateEqualTo(schedulingDate);
			siteCriteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);

			WorkSiteScheduling siteEntity = new WorkSiteScheduling();
			siteEntity.setIsDayoff(BonConstant.DAYOFF_YES);
			siteEntity.setIsDelete(BonConstant.DB_NORMAL);
			workSiteSchedulingMapper.updateByExampleSelective(siteEntity, siteExample);
		} else {
			// 0 - 设置为工作日
			// 4.取消休息日（删除日程，需要重新创建摄控设置）
			WorkSiteSchedulingExample example = new WorkSiteSchedulingExample();
			WorkSiteSchedulingExample.Criteria criteria = example.createCriteria();
			criteria.andSiteIDEqualTo(domain.getSiteID());
			criteria.andSchedulingDateEqualTo(schedulingDate);

			WorkSiteScheduling entity = new WorkSiteScheduling();
			entity.setIsDelete(BonConstant.DB_DELETE);
			entity.setIsDayoff(domain.getIsDayoff());
			workSiteSchedulingMapper.updateByExampleSelective(entity, example);
		}

		return result;
	}

	// 工位对象
	private WorkSiteSeat getSiteSeat(Integer siteID, Integer siteSchID, Date schedulingDate, Integer seatGroupIndex,
			Integer authorID, String author) {
		WorkSiteSeat siteSeat = new WorkSiteSeat();
		siteSeat.setSiteID(siteID);
		siteSeat.setSiteSchedulingID(siteSchID);
		siteSeat.setSchedulingDate(schedulingDate); // 摄控日期
		siteSeat.setSeatGroupIndex(seatGroupIndex); // 工位分组序号（从1开始自动排列）
		siteSeat.setIsDelete(BonConstant.DB_NORMAL);
		siteSeat.setCreatetime(Calendar.getInstance().getTime());
		siteSeat.setAuthorID(authorID);
		siteSeat.setAuthor(author);
		return siteSeat;
	}

	// 席位对象
	private WorkSeatScheduling getSeatScheduling(WorkSiteSeat siteSeat, Date planStartOn, Integer seatGroupIndex,
			Integer authorID, String author) {
		WorkSeatScheduling seatScheduling = new WorkSeatScheduling();
		seatScheduling.setSiteID(siteSeat.getSiteID());
		seatScheduling.setSiteSchedulingID(siteSeat.getSiteSchedulingID());
		seatScheduling.setSiteSeatID(siteSeat.getId());
		seatScheduling.setSeatGroupIndex(seatGroupIndex);
		seatScheduling.setSchedulingDate(siteSeat.getSchedulingDate());
		seatScheduling.setPlanStartOn(planStartOn);
		seatScheduling.setStatus(BonConstant.SEAT_STATUS_ENABLE);
		seatScheduling.setIsDelete(BonConstant.DB_NORMAL);
		seatScheduling.setAuthorID(authorID);
		seatScheduling.setAuthor(author);
		return seatScheduling;
	}

	public String getWeekday(Calendar calendar) {
		if (null == calendar) {
			return "-1";
		}
		int weekday = calendar.get(Calendar.DAY_OF_WEEK);
		switch (weekday) {
		case Calendar.MONDAY:
			return "1";
		case Calendar.TUESDAY:
			return "2";
		case Calendar.WEDNESDAY:
			return "3";
		case Calendar.THURSDAY:
			return "4";
		case Calendar.FRIDAY:
			return "5";
		case Calendar.SATURDAY:
			return "6";
		default:
			return "7";
		}
	}
}
